package com.mall.order.services;

import com.mall.order.OrderCoreService;
import com.mall.order.biz.TransOutboundInvoker;
import com.mall.order.biz.context.AbsTransHandlerContext;
import com.mall.order.biz.factory.OrderProcessPipelineFactory;
import com.mall.order.constant.OrderRetCode;
import com.mall.order.constants.OrderConstants;
import com.mall.order.dal.entitys.Order;
import com.mall.order.dal.entitys.OrderItem;
import com.mall.order.dal.entitys.Stock;
import com.mall.order.dal.persistence.OrderItemMapper;
import com.mall.order.dal.persistence.OrderMapper;
import com.mall.order.dal.persistence.OrderShippingMapper;
import com.mall.order.dal.persistence.StockMapper;
import com.mall.order.dto.*;
import com.mall.order.utils.ExceptionProcessorUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.List;

/**
 * cskaoyan
 */
@Slf4j
@Component
@Service(cluster = "failfast")
public class OrderCoreServiceImpl implements OrderCoreService {

    @Autowired
    OrderMapper orderMapper;

    @Autowired
    OrderItemMapper orderItemMapper;

    @Autowired
    OrderShippingMapper orderShippingMapper;

    @Autowired
    StockMapper stockMapper;

    @Autowired
    OrderProcessPipelineFactory orderProcessPipelineFactory;


    /**
     * 创建订单的处理流程
     *
     * @param request
     * @return
     */
    @Override
    public CreateOrderResponse createOrder(CreateOrderRequest request) {
        CreateOrderResponse response = new CreateOrderResponse();
        try {
            //创建pipeline对象
            TransOutboundInvoker invoker = orderProcessPipelineFactory.build(request);

            //启动pipeline
            invoker.start(); //启动流程（pipeline来处理）

            //获取处理结果
            AbsTransHandlerContext context = invoker.getContext();

            //把处理结果转换为response
            response = (CreateOrderResponse) context.getConvert().convertCtx2Respond(context);
        } catch (Exception e) {
            log.error("OrderCoreServiceImpl.createOrder Occur Exception :" + e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }
        return response;
    }


    /**
     * 支付成功后更新订单状态
     *
     * @param orderId
     * @return
     */
    @Override
    public boolean payOrderSuccess(String orderId) {
        Order order = new Order();
        order.setOrderId(orderId);
        //改成已支付
        order.setStatus(1);
        order.setPaymentTime(new Date());
        order.setUpdateTime(new Date());
        Example example = new Example(Order.class);
        example.createCriteria().andEqualTo("orderId", orderId);
        int i = orderMapper.updateByExampleSelective(order, example);
        if (i != 1) {
            return false;
        }
        return true;
    }

    @Override
    @Transactional
    public boolean updateStockStatus(String orderId) {
        Example example = new Example(OrderItem.class);
        example.createCriteria().andEqualTo("orderId", orderId);
        List<OrderItem> orderItems = orderItemMapper.selectByExample(example);
        Example stockExample = new Example(Stock.class);

        if (orderItems.size() < 1) {
            return false;
        }
        for (OrderItem orderItem : orderItems) {
            Integer num = orderItem.getNum();
            Long itemId = orderItem.getItemId();
            stockExample.createCriteria().andEqualTo("itemId", itemId);
            List<Stock> stocks = stockMapper.selectByExample(stockExample);
            if (stocks.size() != 1) {
                return false;
            }
            Integer lockCount = stocks.get(0).getLockCount();
            log.info("原本的lockCount" + lockCount);
            Stock stock = new Stock();
            stock.setLockCount(lockCount - num);
            log.info("现在的lockCount" + stock.getLockCount());
            stock.setItemId(itemId);
            int affectedRows = stockMapper.updateByExampleSelective(stock, stockExample);
            if (affectedRows != 1) {
                return false;
            }
        }
        return true;
    }

}
